#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "SerialPort.h"

mainwindow :: mainwindow(QWidget *parent) :   QMainWindow(parent),   ui(new Ui::mainwindow)
{

    ui->setupUi(this);

    this->sp = new SerialPort();

    this->timerRead = new QTimer(parent);
    this->timerRead->start(1000);




    QObject::connect(timerRead, SIGNAL(timeout()), this, SLOT(readStatus()));
    QObject::connect(sp, SIGNAL(portOpened()), this, SLOT(portOn()));
    QObject::connect(sp, SIGNAL(portClosed()), this, SLOT(portOff()));
    QObject::connect(sp, SIGNAL(portFailed()), this, SLOT(portFailed()));
    QObject::connect(sp, SIGNAL(dataReady()), this, SLOT(dataListener()));
    QObject::connect(this, SIGNAL(keyLeftPressed()), this, SLOT(on_btGauche_pressed()));
    QObject::connect(this, SIGNAL(keyRightPressed()), this, SLOT(on_btDroite_pressed()));
    QObject::connect(this, SIGNAL(keyUpPressed()), this, SLOT(on_btAvancer_pressed()));
    QObject::connect(this, SIGNAL(keyDownPressed()), this, SLOT(on_btReculer_pressed()));
    QObject::connect(this, SIGNAL(keyLeftReleased()), this, SLOT(on_btGauche_released()));
    QObject::connect(this, SIGNAL(keyRightReleased()), this, SLOT(on_btDroite_released()));
    QObject::connect(this, SIGNAL(keyUpReleased()), this, SLOT(on_btAvancer_released()));
    QObject::connect(this, SIGNAL(keyDownReleased()), this, SLOT(on_btReculer_released()));


}

mainwindow::~mainwindow()
{
    delete ui;
}

void mainwindow::on_actionOuvrir_triggered(bool checked)
{
        sp->show();

}

void mainwindow::on_actionFermer_triggered(bool checked)
{
        sp->closePort();
}

void mainwindow::on_actionQuitter_triggered(bool checked)
{
        this->close();
}

void mainwindow::on_btSend_clicked()
{
        QString text=ui->linInputText->text();
        QByteArray bytes=text.toAscii();

        sp->send(bytes.size(),bytes.data());

        if(portOpen)
        {
                ui->txtSerialLog->append("<font color=blue>"+text+"</font>");
        }
        else
        {
                ui->txtSerialLog->append("<font color=red>"+text+"</font>");
        }
        ui->linInputText->clear();
}

void mainwindow::portOn()
{
        QMainWindow::statusBar()->showMessage("Port open");
        portOpen=true;
        ui->actionOuvrir->setDisabled(true);
        ui->actionFermer->setEnabled(true);
}

void mainwindow::portOff()
{
        QMainWindow::statusBar()->showMessage("Port closed");
        portOpen=false;
        ui->actionOuvrir->setEnabled(true);
        ui->actionFermer->setDisabled(true);
}

void mainwindow::portFailed()
{
        QMainWindow::statusBar()->showMessage("Port failed");
        portOpen=false;
}

void mainwindow::dataListener()
{
        char buffer[256];
        int rec=sp->receive(255,buffer);
        buffer[rec]='\0';
        ui->txtSerialLog->append(buffer);
}

int mainwindow::on_btAvancer_pressed()
{
    if(writeCommand(CMD_AVANCER))
        return -1;
    else
        return 0;
}

int mainwindow::on_btReculer_pressed()
{
    if(writeCommand(CMD_RECULER))
        return -1;
    else
        return 0;
}

int mainwindow::on_btGauche_pressed()
{
    if(writeCommand(CMD_GAUCHE))
        return -1;
    else
        return 0;
}

int mainwindow::on_btDroite_pressed()
{
    if(writeCommand(CMD_DROITE))
        return -1;
    else
        return 0;

}

int mainwindow::on_btAvancer_released()
{
    if(writeCommand(CMD_ARRETER))
        return -1;
    else
        return 0;
}

int mainwindow::on_btReculer_released()
{
    if(writeCommand(CMD_ARRETER))
        return -1;
    else
        return 0;
}

int mainwindow::on_btGauche_released()
{
    if(writeCommand(CMD_ARRETER))
        return -1;
    else
        return 0;
}

int mainwindow :: on_btSuiviLigne_clicked()
{
    if(writeCommand(CMD_SUIVILIGNE))
        return -1;
    else
        return 0;
}


int mainwindow::on_btDroite_released()
{
    if(writeCommand(CMD_ARRETER))
        return -1;
    else
        return 0;
}

int mainwindow :: writeCommand(char c)
{
    char dataRead[2];
    char ackNack[1];

    if(portOpen)
    {
        sp->send(1,&c);
        sp->receive(2,dataRead);
        if(dataRead[0]==c && dataRead[1]==ACK)
        {
            ackNack[0]=ACK;
            sp->send(1,ackNack);
            return 0;
        }
        else
        {
            ackNack[0]=NACK;
            sp->send(1,ackNack);
            return -1;
        }
    }
    else
        return -1;

}
// a chaque 1s on arrive ici (signal timeout du timerRead)
int mainwindow:: readStatus()
{
    char checksum = 0;
    char dataRead[N_READ];

    if(portOpen)
    {
        if(writeCommand(CMD_READSTATUS))
            return -1;
        else
        {
            sp->receive(N_READ,dataRead);
            // on exclu l'octet du cks dans la somme
            for(int i=0;i<N_READ-1;i++)
                checksum += dataRead[i];
            if(checksum == dataRead[N_READ-1])
                return 0;
            else
                return -1;
        }
    }
    else
        return -1;
}

 void mainwindow :: keyPressEvent(QKeyEvent *qkeyevent)
 {
    if(ui->fond->hasFocus() && qkeyevent->isAutoRepeat())
    {
        switch(qkeyevent->key())
        {
            case Qt::Key_Left:
                ui->btGauche->setDown(true);
                emit(keyLeftPressed());

                break;
            case Qt::Key_Right:
                emit(keyRightPressed());
                break;
            case Qt::Key_Up:
                emit(keyUpPressed());
                break;
            case Qt::Key_Down:
                emit(keyDownPressed());
                break;
            default:
                break;
        }
    }
 }

 void mainwindow :: keyReleaseEvent (QKeyEvent *qkeyevent)
 {
    switch(qkeyevent->key())
    {
        case Qt::Key_Left:
            ui->btGauche->setDown(false);
            emit(keyLeftReleased());
        break;
        case Qt::Key_Right:
            emit(keyRightReleased());
        break;
        case Qt::Key_Up:
            emit(keyUpReleased());
        break;
        case Qt::Key_Down:
            emit(keyDownReleased());
        break;
    }
 }
